package cn.huixh.blindbox.utils;

import cn.huixh.blindbox.common.Common;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTException;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSignerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Date;


/**
 * @author huixh
 * @version 1.0
 * @date 2022/5/8 18:35
 */
@Slf4j
@Component
public class JwtUtil {

    /**
     * 过期时间10000分钟
     */
    private static final Integer EXPIRE_TIME = Common.EXPIRE_TIME / 60;

    /**
     * 加密密钥
     */
    private static final byte[] KEY = Common.JWT_KEY.getBytes(StandardCharsets.UTF_8);

    /**
     * 生成token
     *
     * @param id    用户id
     * @param email 用户名 or 邮箱
     * @return token
     */
    public String createToken(String id, String email) {

        Date nowDate = new Date();

        return JWT.create()
                .setHeader("alg", "HS256")
                .setHeader("typ", "JWT")
                .setIssuer("blindbox")
                .setExpiresAt(DateUtil.offsetMinute(nowDate, EXPIRE_TIME))
                .setNotBefore(nowDate)
                .setIssuedAt(nowDate)
                .setJWTId(id)
                .setPayload("email", email)
                .setSigner("HS256", KEY)
                .setCharset(StandardCharsets.UTF_8)
                .sign();
    }

    /**
     * 验证 token 是否有效
     *
     * @param token token
     * @return true 有效 false 无效
     */
    public Boolean verify(String token) {
        try {
            JWTValidator
                    .of(token)
                    .validateAlgorithm(JWTSignerUtil.hs256(KEY))
                    .validateDate();
            return true;
        } catch ( ValidateException | JWTException e ) {
            log.error(e.getMessage());
            return false;
        }
    }

    /**
     * 获取 jwt 携带属性
     *
     * @param name  属性名
     * @param token token
     * @return 属性值
     */
    public String getPayload(String name, String token) {
        return JWT.of(token).getPayload().getClaim(name).toString();
    }


}
